<?php
//
//	file: admin/admin_acp_protect.php
//	author: ptirhiik
//	begin: 17/08/2007
//	version: 1.6.0 - 17/08/2007
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//

//
// included from pagestart: check if we need to install the panels, else check if the panel is authorised
//
if ( isset($in_admin_pagestart) && $in_admin_pagestart )
{
	if ( !$user->data['session_logged_in'] )
	{
		return;
	}

	if ( !isset($requester) )
	{
		message_die(GENERAL_ERROR, 'error_not_ch');
	}

	// search for the frame_admin panel
	$sql = $result = $script_panels = $root_panel_order = $panel_shortcut = $panel_id = $script = false;
	if ( ($requester != 'admin/index') || (_read('pane', TYPE_NO_HTML) == 'left') )
	{
		$sql = 'SELECT *
					FROM ' . CP_PANELS_TABLE . '
					WHERE panel_shortcut = \'frame_admin\'
						AND panel_main = 0';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$script_panels = ($row = $db->sql_fetchrow($result)) ? array($row['panel_id'] => array('parent' => false, 'shortcut' => $row['panel_shortcut'])) : false;
		$root_panel_order = $row ? $row['panel_order'] : false;
		$db->sql_freeresult($result);

		if ( !$script_panels && ($requester != 'admin/admin_acp_protect') )
		{
			redirect('./admin/admin_acp_protect.' . $config->ext . '?mode=proceed&amp;sid=' . $user->data['session_id']);
		}
	}

	// search for the panel
	if ( $script_panels )
	{
		$panel_shortcut = preg_replace('#^admin/#', '', $requester);
		$sql = 'SELECT *
					FROM ' . CP_PANELS_TABLE . '
					WHERE panel_order > ' . intval($root_panel_order) . '
						ORDER BY panel_order';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		while ( $row = $db->sql_fetchrow($result) )
		{
			// outside the branch
			if ( !isset($script_panels[ $row['panel_main'] ]) )
			{
				break;
			}

			// add the panel to the branch
			$script_panels[ $row['panel_id'] ] = array('parent' => $row['panel_main'], 'shortcut' => $row['panel_shortcut']);

			// we have found the panel
			if ( $row['panel_shortcut'] == $panel_shortcut )
			{
				$panel_id = $row['panel_id'];
				break;
			}
		}
		$db->sql_freeresult($result);
	}

	// ok, we have the panel id: check the auth for the whole branch
	if ( $panel_id !== false )
	{
		$user->get_cache(POST_PANELS_URL);
		while ( $panel_id !== false )
		{
			if ( !$user->auth(POST_PANELS_URL, 'access', $panel_id) )
			{
				message_die(GENERAL_ERROR, 'Not_Authorised');
			}
			$panel_id = $script_panels[$panel_id]['parent'];
		}
	}
	// maybe we are on left index
	else if ( $script_panels && ($requester == 'admin/index') )
	{
		$user->get_cache(POST_PANELS_URL);
		foreach ( $script_panels as $panel_id => $dummy )
		{
			$script = $script_panels[$panel_id]['shortcut'];
			while ( $panel_id !== false )
			{
				if ( !$user->auth(POST_PANELS_URL, 'access', $panel_id) && ($script_panels[ $script_panels[$panel_id]['parent'] ]['shortcut'] != 'frame_admin') )
				{
					$denied_scripts[] = $script;
					break;
				}
				$panel_id = $script_panels[$panel_id]['parent'];
			}
		}
	}
	unset($sql, $result, $script_panels, $root_panel_order, $panel_shortcut, $panel_id, $script);
	return;
}

//
// included from index.php?pane=left: add it to the menu
//
define('IN_PHPBB', true);

$file = basename(__FILE__);
if( !empty($setmodules) )
{
	$module['030_Control_panels']['00_Add_frame_panels'] = $file;
	return;
}

//
// called from the url
//
$phpbb_root_path = './../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
$requester = 'admin/admin_acp_protect';
$no_page_header = true;
require('./pagestart.' . $phpEx);

// the user rejected the creation/update
if ( _button('cancel') )
{
	redirect('./admin/index.' . $config->ext . '?pane=right&amp;sid=' . $user->data['session_id']);
}

// proceed
if ( (_read('mode', TYPE_NO_HTML) == 'proceed') || _button('confirm') )
{
	// first step: get the admin menu
	$module = array();
	if ( $dir = @opendir('.') )
	{
		$setmodules = true;
		while( $file = @readdir($dir) )
		{
			if ( preg_match('/^admin_.*?\.' . $phpEx . '$/', $file) && !in_array(preg_replace('/\.' . $phpEx . '$/i', '', $file), $denied_scripts) )
			{
				include('./' . $file);
			}
		}
		@closedir($dir);
		unset($setmodules);
	}

	// format the scripts
	$scripts = array('frame_admin' => array(
		'name' => 'frame_admin',
		'shortcut' => 'frame_admin',
		'parent' => false,
	));
	$files = array();
	if ( !empty($module) )
	{
		ksort($module);
		foreach ( $module as $cat => $action_array )
		{
			$name = preg_replace('#^\d*?_(.*)#i', '\1', $cat);
			$shortcut_full = 'frame_admin.' . $name;
			$scripts[$shortcut_full] = array(
				'name' => $name,
				'shortcut' => $name,
				'parent' => 'frame_admin',
			);
			if ( !empty($action_array) )
			{
				$color = false;
				ksort($action_array);
				foreach ( $action_array as $action => $file )
				{
					$file = substr($file, 0, strlen($file) - strlen(strrchr($file, '?')));
					$file = substr($file, 0, strlen($file) - strlen(strrchr($file, '.')));
					if ( !isset($files[$file]) )
					{
						$files[$file] = true;
						$scripts[$shortcut_full . '.' . $file] = array(
							'name' => preg_replace('#^\d*?_(.*)#i', '\1', $action),
							'shortcut' => $file,
							'parent' => $shortcut_full,
						);
					}
				}
			}
		}
	}
	unset($module);
	unset($files);

	// second step: read the panels, and get an index per full shortcut
	// first get the root panel
	$script_panels = $shortcuts = array();
	$root_panel_id = false;
	$sql = 'SELECT *
				FROM ' . CP_PANELS_TABLE . '
				WHERE panel_shortcut = \'frame_admin\'
					AND panel_main = 0';
	$result = $db->sql_query($sql, false, __LINE__, __FILE__);
	if ( ($row = $db->sql_fetchrow($result)) )
	{
		$root_panel_id = $row['panel_id'];
		$row['shortcut_full'] = $row['panel_shortcut'];
		$script_panels[ $row['panel_id'] ] = $row;
		$shortcuts[ $row['shortcut_full'] ] = $row['panel_id'];
	}
	$db->sql_freeresult($result);

	// then read the branch
	if ( $root_panel_id !== false )
	{
		$sql = 'SELECT *
					FROM ' . CP_PANELS_TABLE . '
					WHERE panel_order > ' . intval($script_panels[$root_panel_id]['panel_order']) . '
						ORDER BY panel_order';
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		while ( $row = $db->sql_fetchrow($result) )
		{
			// outside the branch
			if ( !isset($script_panels[ $row['panel_main'] ]) )
			{
				break;
			}

			// add the panel to the branch
			$row['shortcut_full'] = $script_panels[ $row['panel_main'] ]['shortcut_full'] . '.' . $row['panel_shortcut'];
			$script_panels[ $row['panel_id'] ] = $row;
			$shortcuts[ $row['shortcut_full'] ] = $row['panel_id'];
		}
		$db->sql_freeresult($result);
	}

	// get the update status
	$deleted = 0;
	$updated = 0;
	$inserted = 0;

	// get the panels to delete
	if ( !empty($script_panels) )
	{
		$delete_panel_ids = array();
		$order_inc = 0;
		foreach ( $shortcuts as $shortcut => $panel_id )
		{
			$script_panels[$panel_id]['panel_order'] -= $order_inc;
			$local_update = false;

			// the panel does no more match an existing script
			if ( !isset($scripts[$shortcut]) )
			{
				$delete_panel_ids[] = $panel_id;
				$order_inc += 10;

				// update the panels order
				$sql = 'UPDATE ' . CP_PANELS_TABLE . '
							SET panel_order = panel_order - ' . $order_inc . '
							WHERE panel_order > ' . intval($script_panels[$panel_id]['panel_order']);
				$db->sql_query($sql, false, __LINE__, __FILE__);

				// remove the panel from our buffers
				unset($shortcuts[$shortcut]);
				unset($script_panels[$panel_id]);
			}

			// the script still exists: check if it requires an update
			else
			{
				// root panel
				if ( $shortcut == 'frame_admin' )
				{
					if ( $script_panels[$panel_id]['panel_main'] != 0 )
					{
						$local_update = true;
						$sql = 'UPDATE ' . CP_PANELS_TABLE . '
									SET panel_main = 0
									WHERE panel_id = ' . intval($panel_id);
						$db->sql_query($sql, false, __LINE__, __FILE__);

						// update our buffer
						$script_panels[$panel_id]['panel_main'] = 0;
					}
				}
				// other panels
				else
				{
					// get the parent panel
					if ( $script_panels[ $script_panels[$panel_id]['panel_main'] ]['shortcut_full'] != $scripts[$shortcut]['parent'] )
					{
						$local_update = true;
						$sql = 'UPDATE ' . CP_PANELS_TABLE . '
									SET panel_main = ' . intval($shortcuts[ $scripts[$shortcut]['parent'] ]) . '
									WHERE panel_id = ' . intval($panel_id);
						$db->sql_query($sql, false, __LINE__, __FILE__);

						// update our buffer
						$script_panels[$panel_id]['panel_main'] = $shortcuts[ $scripts[$shortcut]['parent'] ];
					}
				}
				// ensure the names are still the same
				if ( $script_panels[$panel_id]['panel_name'] != $scripts[$shortcut]['name'] )
				{
					$local_update = true;
					$sql = 'UPDATE ' . CP_PANELS_TABLE . '
								SET panel_name = ' . $db->sql_type_cast($scripts[$shortcut]['name']) . '
								WHERE panel_id = ' . intval($panel_id);
					$db->sql_query($sql, false, __LINE__, __FILE__);

					// update our buffer
					$script_panels[$panel_id]['panel_name'] = $scripts[$shortcut]['name'];
				}
				// increment the row counter
				if ( $local_update )
				{
					$updated++;
				}
			}
		}

		// proceed with the deletes
		if ( ($deleted = count($delete_panel_ids)) )
		{
			// delete auths
			$sql = 'DELETE FROM ' . AUTHS_TABLE . '
						WHERE obj_type = \'' . POST_PANELS_URL . '\'
							AND obj_id IN(' . implode(', ', $delete_panel_ids) . ')';
			$db->sql_query($sql, false, __LINE__, __FILE__);

			// delete fields: shouldn't occur
			$sql = 'DELETE FROM ' . CP_FIELDS_TABLE . '
						WHERE panel_id IN(' . implode(', ', $delete_panel_ids) . ')';
			$db->sql_query($sql, false, __LINE__, __FILE__);

			// delete the panel
			$sql = 'DELETE FROM ' . CP_PANELS_TABLE . '
						WHERE panel_id IN(' . implode(', ', $delete_panel_ids) . ')';
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}
	}

	// we have dealt with deletetion and updates, we have to deal now with insertion and order
	if ( !empty($scripts) )
	{
		// init current order
		if ( ($no_inc = !isset($shortcuts['frame_admin'])) )
		{
			// get the last panels order
			$sql = 'SELECT MAX(panel_order) AS max_panel_order
						FROM ' . CP_PANELS_TABLE;
			$result = $db->sql_query($sql, false, __LINE__, __FILE__);
			$current_order = ($row = $db->sql_fetchrow($result)) ? $row['max_panel_order'] + 10 : 10;
			$db->sql_freeresult($result);
		}
		else
		{
			$current_order = $script_panels[ $shortcuts['frame_admin'] ]['panel_order'];
		}

		// go on and process each script
		foreach ( $scripts as $shortcut => $data )
		{
			// insertion
			if ( !isset($shortcuts[$shortcut]) )
			{
				$inserted++;

				// make some rooms
				if ( !$no_inc )
				{
					$sql = 'UPDATE ' . CP_PANELS_TABLE . '
								SET panel_order = panel_order + 10
								WHERE panel_order >= ' . $current_order;
					$db->sql_query($sql, false, __LINE__, __FILE__);
				}

				// do the same for the buffer
				foreach ( $script_panels as $panel_id => $dummy )
				{
					if ( $script_panels[$panel_id]['panel_order'] >= $current_order )
					{
						$script_panels[$panel_id]['panel_order'] += 10;
					}
				}

				// create the panel
				$fields = array(
					'panel_shortcut' => $data['shortcut'],
					'panel_name' => $data['name'],
					'panel_main' => $shortcut == 'frame_admin' ? 0 : $shortcuts[ $data['parent'] ],
					'panel_order' => $current_order,
					'panel_file' => '',
					'panel_auth_type' => '',
					'panel_auth_name' => '',
					'panel_hidden' => false,
				);
				$row = $fields;
				$sql = 'INSERT INTO ' . CP_PANELS_TABLE . '
							(' . $db->sql_fields('fields', $fields) . ') VALUES(' . $db->sql_fields('values', $fields) . ')';
				$db->sql_query($sql, false, __LINE__, __FILE__);
				$row['panel_id'] = $db->sql_nextid();

				// update our buffers
				$row['shortcut_full'] = $shortcut;
				$shortcuts[$shortcut] = $row['panel_id'];
				$script_panels[ $row['panel_id'] ] = $row;
			}

			// re-ordering
			else if ( $script_panels[ $shortcuts[$shortcut] ]['panel_order'] < $current_order )
			{
				$updated++;
				$old_order = $script_panels[ $shortcuts[$shortcut] ]['panel_order'];

				// shift back one pos between the old and new order
				$sql = 'UPDATE ' . CP_PANELS_TABLE . '
							SET panel_order = panel_order - 10
							WHERE panel_order BETWEEN ' . (intval($old_order) + 1) . ' AND ' . intval($current_order);
				$db->sql_query($sql, false, __LINE__, __FILE__);

				// update the current order
				$sql = 'UPDATE ' . CP_PANELS_TABLE . '
							SET panel_order = ' . intval($current_order) . '
							WHERE panel_id = ' . intval($shortcuts[$shortcut]);
				$db->sql_query($sql, false, __LINE__, __FILE__);

				// do the same for the buffer
				foreach ( $script_panels as $panel_id => $dummy )
				{
					if ( $panel_id == $shortcuts[$shortcut] )
					{
						$script_panels[$panel_id]['panel_order'] = $current_order;
					}
					else if ( ($script_panels[$panel_id]['panel_order'] > $old_order) && ($script_panels[$panel_id]['panel_order'] <= $current_order) )
					{
						$script_panels[$panel_id]['panel_order'] -= 10;
					}
				}
			}
			else if ( $script_panels[ $shortcuts[$shortcut] ]['panel_order'] > $current_order )
			{
				$updated++;
				$old_order = $script_panels[ $shortcuts[$shortcut] ]['panel_order'];

				// update the current order
				$sql = 'UPDATE ' . CP_PANELS_TABLE . '
							SET panel_order = ' . intval($current_order) . '
							WHERE panel_id = ' . intval($shortcuts[$shortcut]);
				$db->sql_query($sql, false, __LINE__, __FILE__);

				// shift up one pos between the new and old order
				$sql = 'UPDATE ' . CP_PANELS_TABLE . '
							SET panel_order = panel_order + 10
							WHERE panel_order BETWEEN ' . intval($current_order) . ' AND ' . (intval($old_order) - 1);
				$db->sql_query($sql, false, __LINE__, __FILE__);

				// do the same for the buffer
				foreach ( $script_panels as $panel_id => $dummy )
				{
					if ( ($script_panels[$panel_id]['panel_order'] >= $current_order) && ($script_panels[$panel_id]['panel_order'] < $old_order) )
					{
						$script_panels[$panel_id]['panel_order'] += 10;
					}
					else if ( $panel_id == $shortcuts[$shortcut] )
					{
						$script_panels[$panel_id]['panel_order'] = $current_order;
					}
				}
			}

			// next panel
			$current_order += 10;
		}
	}
	unset($scripts);
	unset($script_panels, $shortcuts);

	// all done, let's recache the panels
	if ( $updated || $deleted || $inserted )
	{
		if ( !class_exists('cp_panels') )
		{
			include($config->url('includes/class_cp'));
		}
		$cp_panels = new cp_panels($requester);
		$cp_panels->read(true);
		unset($cp_panels);

		$sql = 'DELETE FROM ' . USERS_CACHE_TABLE . '
					WHERE cache_id LIKE \'' . POST_PANELS_URL . '%\'';
		$db->sql_query($sql, false, __LINE__, __FILE__);
	}

	// return, depending how we entered
	if ( _read('mode', TYPE_NO_HTML) == 'proceed' )
	{
		redirect('./admin/index.' . $config->ext . '?pane=left&amp;sid=' . $user->data['session_id']);
	}

	// send a confirm message
	$template->assign_vars(array(
		'MESSAGE_TITLE' => $template->lang('Add_frame_panels'),
		'MESSAGE_TEXT' => $template->lang('Add_frame_panels_done'),
	));
	$template->set_filenames(array('body' => 'admin/admin_message_body.tpl'));
}
// confirmation message
else
{
	// send a confirm message
	$template->assign_vars(array(
		'NAVIGATION_BOX' => '',
		'MESSAGE_TITLE' => $template->lang('Add_frame_panels'),
		'MESSAGE_TEXT' => $template->lang('Add_frame_panels_explain'),
		'L_YES' => $template->lang('Yes'),
		'L_NO' => $template->lang('No'),
		'S_CONFIRM_ACTION' => $config->url($requester, '', true),
	));
	$template->set_filenames(array('body' => 'admin/confirm_body.tpl'));
}
include($config->url('admin/page_header_admin'));
$template->pparse('body');
include($config->url('admin/page_footer_admin'));

?>